
#include "Supercharged.h"
#include <time.h>


// Constructor

Supercharged::Supercharged()
{	
	srand((unsigned int) time(NULL));
	dxFont = new TextDX();  // DirectX font
	ball = new Ball();
	paddle = new Paddle();

}


// Destructor

Supercharged::~Supercharged()
{
	releaseAll();           // call onLostDevice() for every graphics item
	SAFE_DELETE(dxFont);
}


// Initializes the game
// Throws GameError on error

void Supercharged::initialize(HWND hwnd)
{
	Game::initialize(hwnd); // throws GameError

	////////////////////////////////////////////////////////
	//  CREATE MACRO/FUNCTION FOR TEXTURE INITIALIZACION  //
	////////////////////////////////////////////////////////
	if (!crosshairTexture.initialize(graphics,CROSSHAIR_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing crosshair texture"));

	addTextureManager(&crosshairTexture);

	if (!blockTexture.initialize(graphics,BLOCK_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing block texture"));

	addTextureManager(&blockTexture);

	if (!ballTexture.initialize(graphics,BALL_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing crosshair texture"));
	addTextureManager(&ballTexture);

	if (!paddleTexture.initialize(graphics,PADDLE_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing crosshair texture"));
	addTextureManager(&paddleTexture);

	if (!buttonTexture.initialize(graphics,BUTTON_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing button texture"));	
	addTextureManager(&buttonTexture);

	if (!bubbleTexture.initialize(graphics,BUBBLE_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing bubble texture"));	
	addTextureManager(&bubbleTexture);

	
	if (!crosshair.initialize(graphics,0,0,0,&crosshairTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing crosshair"));

	if (!ball->initialize(graphics, input, audio, 0, 0, 0, &ballTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing ball"));	

	ball->setX(GAME_WIDTH/2);
	ball->setY(GAME_HEIGHT/2);
	ball->setCollisionRadius(BALL_RADIUS);
	ball->setMass(BALL_MASS);
	D3DXVECTOR2 v;
	v.x = 200 + (rand() % 200);
	v.y = 200 + (rand() % 200);
	ball->setVelocity(v);
	addEntity(ball);

	if (!paddle->initialize(graphics, input, audio, 0, 0, 0, &paddleTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing paddle"));

	//paddle->setX(GAME_WIDTH);
	paddle->setEdge(PADDLE_COLLISION_RECTANGLE);
	paddle->setCollisionType(entityNS::BOX);		
	paddle->setMass(PADDLE_MASS);
	paddle->setY(GAME_HEIGHT - 30);
	addEntity(paddle);


	// initialize DirectX font
	// 18 pixel high Arial
	if(dxFont->initialize(graphics, 18, true, false, "Arial") == false)
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing DirectX font"));

	Game::dxFont.setFontColor(graphicsNS::BLACK);
	dxFont->setFontColor(graphicsNS::BLACK);

	ShowCursor(false);
	graphics->setBackColor(graphicsNS::WHITE);

	lclick = false;
	rclick = false;

	if (!button.initialize(graphics, input, audio, 50, 50, 2, &buttonTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing button"));

	button.setX(GAME_WIDTH/2);
	button.setY(GAME_HEIGHT/2);
	button.setFrames(buttonNS::START_FRAME, buttonNS::END_FRAME);
    button.setCurrentFrame(buttonNS::START_FRAME);
	
	if (!bubble.initialize(graphics, 0, 0, 0, &bubbleTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing crosshair"));
	
	button.setImageOverlay(bubble);

	itemSelector.Initialize(graphics, input, audio);
	itemSelector.setCenterX(GAME_WIDTH/2);
	itemSelector.setCenterY(GAME_HEIGHT/2);
	itemSelector.setSlots(8);
	itemSelector.addItem(ITEM_BLOCK);

	return;
}


// Update all game items

void Supercharged::update()
{	
	
	if (input->isKeyDown(VK_ESCAPE))
		PostQuitMessage(0);

	// Set crosshair possition
	crosshair.setX(input->getMouseX()-crosshair.getWidth()/2);
	crosshair.setY(input->getMouseY()-crosshair.getHeight()/2);

	blockCreation();
	blockDestruction();

	if (input->anyKeyPressed())
	{
		char c = input->getCharIn();
	}

	paddle->setX(input->getMouseX()-paddle->getWidth()/2);
	
	button.update(frameTime);

	itemSelector.update(frameTime);
	
	if (!itemSelector.isActivated() && input->getMouseRButton())
		itemSelector.activate();

	if (itemSelector.isActivated() && !input->getMouseRButton())
		itemSelector.deactivate();


	updateEntities();
		
	
}


// Artificial Intelligence

void Supercharged::ai()
{}


// Handle collisions

void Supercharged::collisions()
{
	entityCollisions();
}


// Render game items

void Supercharged::render()
{
	graphics->spriteBegin();                // begin drawing sprites	
	
	drawEntities();	
	
	itemSelector.draw();
	//button.draw();
	/*
	button.setX(orig_x + 55);
	button.draw();
	
	button.setX(orig_x - 55);
	button.draw();
	
	// Up
	button.setY(orig_y - 55);
	button.draw();

	button.setX(orig_x);
	button.draw();
	
	button.setX(orig_x + 55);
	button.draw();	

	// Down
	button.setY(orig_y + 55);
	button.draw();

	button.setX(orig_x);
	button.draw();

	button.setX(orig_x - 55);
	button.draw();
	
	button.setX(orig_x);
	button.setY(orig_y);
	*/
	

	crosshair.draw();
	graphics->spriteEnd();                  // end drawing sprites
}


// The graphics device was lost.
// Release all reserved video memory so graphics device may be reset.

void Supercharged::releaseAll()
{
	
	dxFont->onLostDevice();
	releaseTextureManagers();
	Game::releaseAll();
	return;
}


// The grahics device has been reset.
// Recreate all surfaces.

void Supercharged::resetAll()
{
	
	resetTextureManagers();
	dxFont->onResetDevice();
	Game::resetAll();
	return;
}

void Supercharged::entityCollisions()
{
	std::list <Entity *>::iterator it1;
	std::list <Entity *>::iterator it2;
	it1 = entities.begin();

	while (it1 != entities.end())
	{
		it2 = entities.begin();
		while (it2 != entities.end())
		{
			if (*it1 != *it2)
			{
				VECTOR2 v;
				v.x = 0;
				v.y = 0;
				if ((*it1)->collidesWith(*(*it2), v))
				{
					if (*it1 == ball)
						ball->bounce(v, *(*it2));
				}
			}
			it2++;
		}
		it1++;
	}
}

void Supercharged::blockCreation()
{
	if (input->getMouseLButton() && !lclick)
	{
		if (input->getMouseY() < BLOCK_CREATION_HEIGHT_LIMIT)
		{
			Block *b = new Block();
			b->initialize(getGraphics(),getInput(),getAudio(),0,0,0,&blockTexture);
			b->setX(input->getMouseX()-b->getWidth()/2);
			b->setY(input->getMouseY()-b->getHeight()/2);	
			b->setEdge(BLOCK_COLLISION_RECTANGLE);
			b->setCollisionType(entityNS::BOX);		
			b->setMass(BLOCK_MASS);
			addEntity(b);
		}
		
		lclick = true;
	}
	if (!input->getMouseLButton() && lclick)
		lclick = false;
}

void Supercharged::blockDestruction()
{
	if (input->getMouseRButton() && !rclick)
	{
		if (input->getMouseY() < BLOCK_CREATION_HEIGHT_LIMIT)
		{
			deleteNearestBlock(input->getMouseX(), input->getMouseY());
		}
		
		rclick = true;
	}
	if (!input->getMouseRButton() && rclick)
		rclick = false;
}

void Supercharged::deleteNearestBlock(float x, float y)
{	
	bool foundAny = false;
	float nearestDistance = 0;
	Entity *nearestEntity = NULL;
	std::list <Entity *>::iterator it;
	it = entities.begin();
	while (it != entities.end())
	{
		// We just want to check blocks
		if (typeid(*(*it)) != typeid(Block))
		{
			it++;
			continue;
		}

		float dX = abs((*it)->getCenterX() - x);
		float dY = abs((*it)->getCenterY() - y);

		if ((dX < 15) && (dY < 15))
		{
			float distance = sqrt(dX * dX + dY * dY);
			if (!foundAny)
			{
				nearestDistance = distance;
				nearestEntity = *it;
				foundAny = true;
			}
			else
			{
				if (distance < nearestDistance)
				{
					nearestDistance = distance;
					nearestEntity = *it;
				}
			}
		}	
		
		it++;
	}

	if (nearestEntity != NULL)
	{
		deleteEntity(nearestEntity);
	}

}